using System;
using System.IO;
using System.Data;
using System.Threading;
using System.Diagnostics;
using System.Collections;
using System.Configuration;
using System.Globalization;
using System.Collections.Generic;


namespace ChunkTransporter
{
	class Config
	{
		public static int ChunkSize
		{
			get
			{
				return ConfigurationManager.AppSettings["ChunkSize"] == null ? 5000 : int.Parse(ConfigurationManager.AppSettings["ChunkSize"]);
			}
		}
		public static int ThreadCount
		{
			get
			{
				return ConfigurationManager.AppSettings["ThreadCount"] == null ? 25 : int.Parse(ConfigurationManager.AppSettings["ThreadCount"]);
			}
		}
		public static int RemotingThresholdTableSize
		{
			get
			{
				return ConfigurationManager.AppSettings["RemotingThresholdTableSize"] == null ? 5000 : int.Parse(ConfigurationManager.AppSettings["RemotingThresholdTableSize"]);
			}
		}

		public static bool RemotingTrim
		{
			get
			{
				return true;
			}
		}

		public static int RemotingTimeout
		{
			get
			{
				return 120;
			}
		}
		public static bool ChunkingEnabled
		{
			get
			{
				return true;
			}
		}

		public static string MarshalMethod
		{
			get
			{
				return "DATATABLE";
			}
		}


	}
	[Serializable]
	public struct Filter
	{
		internal Filter(int firstRecord, int lastRecord)
		{
			Debug.Assert(firstRecord <= lastRecord);
			this.firstRecord = firstRecord;
			this.lastRecord = lastRecord;
		}
		internal int firstRecord, lastRecord;

		public DataRow[] S_doFilter(DataTable raw)
		{
			if (raw.Rows.Count == 0)
				return null;

			if (firstRecord == -1 && lastRecord == -1)
				return null;
			Helper.TRACE("{0}.Snippet({1}, {2})", raw.TableName, firstRecord, lastRecord);
			DataRow[] retval = new DataRow[lastRecord - firstRecord + 1];

			for (int i = firstRecord; i <= Math.Min(lastRecord, raw.Rows.Count - 1); i++)
			{
				try
				{
					retval[i - firstRecord] = raw.Rows[i];
				}
				catch (Exception e)
				{
					Helper.LogException("filter.doFilter() failed on row " + i, e);
				}
			}

			return retval;
		}
	}

	public class Helper
	{
		public static void TRACE(string format, params object[] args)
		{
//			Console.WriteLine(string.Format("{0}> {1}", DateTime.Now.ToString("h:mm:ss", CultureInfo.InvariantCulture), string.Format(format, args)));
			Trace.WriteLine(string.Format(format, args));
		}
		public static void Alert(string format, params object[] args)
		{
			Trace.WriteLine("***   " + string.Format(format, args));
		}
		public static void LogException(string info, Exception e)
		{
			TRACE(string.Format("*** ALERT *** {0} {1} {2} {3}", info, e.GetType(), e.Message, e.ToString()));
			Console.WriteLine(string.Format("*** ALERT *** {0} {1} {2} \n{3}", info, e.GetType(), e.Message, e.ToString()));
		}
		public static string ThreadName
		{
			set
			{
				try { Thread.CurrentThread.Name = value; }
				catch { };
			}
		}
		public static string FormatLong(long l)
		{
			NumberFormatInfo nfi = new CultureInfo("en-GB", false).NumberFormat;
			nfi.NumberDecimalDigits = 0;
			return l.ToString("N", nfi);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="time"></param>
		/// <param name="isWithMilliseconds">
		/// true: 21 Jul 2005 03:47:196 PM
		/// false: 21 Jul 2005 03:47 PM
		/// </param>
		/// <returns></returns>
		public static string Time2DbString(DateTime time, bool isWithMilliseconds)
		{
			DateTimeFormatInfo df = new DateTimeFormatInfo();
			//			if (time.short.ToString() == time.ToShortDateString())
			//			{	// date only
			//				df.LongDatePattern = "MMM dd yyyy";
			//			}
			//			else
			{
				if (isWithMilliseconds)
					df.LongDatePattern = "MMM dd yyyy hh:mm:ss.fff tt";
				else
					df.LongDatePattern = "MMM dd yyyy hh:mm:ss tt";
			}
			return time.ToString("D", df);
		}



	}

}